package com.lstimeline.statuschecker;

import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import org.htmlparser.Parser;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import com.lstimeline.utility.Validation;

/**
 * Cornell seems to have a weak auth system. A static url shows your application status.
 * The username/password combination gets you a APPID, and two cookies valid for at least 30 years
 * @author Harry
 *
 */
public class CornellLogic extends AbstractStatusChecker {
	private static final int WORD_LIMIT = 47;
	private String urlString = "http://support.law.cornell.edu/admissions/status/Login.cfm";
	
	/**
	 * Get CFID, CFTOKEN
	 * Set-Cookie: CFID=331783;expires=Tue, 05-Jul-2039 01:26:56 GMT;path=/
	 * Set-Cookie: CFTOKEN=49440226;expires=Tue, 05-Jul-2039 01:26:56 GMT;path=/
	 */
	private void connectForCookies() {
		setupGETConnection(urlString);
		receiveCookies();
	}
	
	protected String getLogonString(String username, String password) throws ParserException, UnsupportedEncodingException {
		StringBuilder builder = new StringBuilder();
		queryBuilder(builder, "UserName", username);
		queryBuilder(builder, "Pword", password);
		queryBuilder(builder, "Submit", "Submit");
		// remove the last '&'
		builder.deleteCharAt(builder.length() - 1);
		
		return builder.toString();
	}
	
	//Cornell
	//Post logon information to logon.aspx
	protected void logon(String username, String password) throws Exception{
		String logonString = getLogonString(username, password);
		urlString = "http://support.law.cornell.edu/admissions/status/DoLogin.cfm?Attempt=0";
		setupPOSTConnection(urlString, logonString.length());
		
		// post the login query
		// Username, Password
		PrintWriter out = new PrintWriter(conn.getOutputStream());
		out.write(logonString);
		out.flush();
		out.close();
		
		//Important: to ignore response so that the connection can be recylcled.
		conn.getInputStream().close();
		
		//STATUSCOOKIE
		receiveCookies();
	}
	
	private NodeList retrieve() throws Exception{
		//http://support.law.cornell.edu/admissions/status/ReturnUser.cfm?AppID=29137&CFID=331783&CFTOKEN=49440226
		urlString = "http://support.law.cornell.edu/admissions/status/" + conn.getHeaderField("Location");
		
		//if retrieval failed
		if(urlString == null) {
			return null;
		}
		
		setupGETConnection(urlString);
		
		parser = new Parser(conn);
		NodeList nodes = parser.parse(new TagNameFilter("td"));
		
		return nodes;
	}
	
	@Override
	public String getStatusMessage(String username, String password) {
		//loosely sanitize username and password
		if(!Validation.isGeneralLoginWellFormed(username, password)) {
			statusCode = AUTH_FAIL;
			return null;
		}
		
		//Get CFID, CFTOKEN
		connectForCookies();
		
		NodeList nodes = null;
		try {
			logon(username, password);
			
			nodes = retrieve();
			
			if(nodes == null || nodes.size() != 3) {
				statusCode = AUTH_FAIL;
				return null;
			} else {
				statusCode = SUCCESS;
				StringBuilder responseString = new StringBuilder();
				responseString.append(nodes.elementAt(0).toPlainTextString());
				responseString.append(": ");
				responseString.append(nodes.elementAt(2).toPlainTextString().substring(0, WORD_LIMIT));
				responseString.append("...");
				return responseString.toString();
			}
		} catch (Exception e) {
			statusCode = ERR;
			e.printStackTrace();
			return null;
		}
	}

}
